import * as d3 from "d3";

/*
* 来自: https://bl.ocks.org/mbostock/b07f8ae91c5e9e45719c
* */

let rainbowPack = (function () {

    let svg = undefined;
    let size = undefined;
    let circles = undefined;

    let getAmount = function () {
        /*
        * 根据端的不同,分配不同的数量
        * 避免卡顿
        * */
        let user_agent = navigator.userAgent;
        let Android = new RegExp('Android').test(user_agent);
        let Mobile = new RegExp('Mobile').test(user_agent);
        if(Android&&Mobile){
            return 40;
        }else{
            return 2000;
        }
    };

    let init = function (svgId,width,height) {
        /*
        * svgId: svg标签ID
        * width: svg标签宽度
        * height: svg标签高度
        * */
        // console.log(getAmount());
        svg = d3.select(svgId);
        svg
            .style('width',width)
            .style('height',height);
        let _width = svg.attr("width");
        let _height = svg.attr("height");
        size = Math.max(_width, _height);
        let halfWidth = width/2;
        let halfHeight = height/2;
        circles = d3.packSiblings(d3.range(getAmount())//range会生成一个数组,数量跟参数一致,且值对应数组长度
            .map(d3.randomUniform(8, 26))//对数组的每个值在一定范围内取随机值
            /*
            * 接收数组中的值,并返回一个对象,根据源码得知
            * packSiblings会根据输入的,包含属性r的对象,生成其余所需要的x和y坐标
            * 最后会生成一个数组,该数组每个元素都是办好r,x和y属性的对象
            * */
            .map(function(r) { return {r: r}; }))
            //满足过滤器的值保留否则踢出
            // .filter(function(d) { return -500 < d.x && d.x < 500 && -500 < d.y && d.y < 500; });
            .filter(function(d) { return -halfWidth < d.x && d.x < halfWidth && -halfHeight < d.y && d.y < halfHeight; });
    };




    let run = function (svgId,width,height) {

        init(svgId,width,height);
        // console.log('rainbow');
        /*
        * 第一个cx和cy设置起点,第二个设置终点
        * style和attr第一个参数是属性名,第二个参数是属性值
        * cx和cy是svg circle标签的x和y坐标
        * */

        svg
            .select("g")
            .attr("transform", function() {let _w =width/2;let _h=height/2; return "translate("+_w+','+_h+')';})
            .selectAll("circle")
            .data(circles)
            .enter().append("circle")
            //该style的回调函数不仅用于颜色设置,还会影响圆球的初始位置
            .style("fill", function(d) { d.angle = Math.atan2(d.y, d.x); return d3.rgb(randomColor(),randomColor(),randomColor()); })
            .attr("cx", function(d) { return Math.cos(d.angle) * (size / Math.SQRT2 + width); })
            .attr("cy", function(d) { return Math.sin(d.angle) * (size / Math.SQRT2 + height); })
            .attr("r", function(d) { return d.r - 0.25; })
            .transition()
            .ease(d3.easeCubicOut)
            .delay(function(d) { return Math.sqrt(d.x * d.x + d.y * d.y) * 20; })
            .duration(1000)
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });

    };

    let randomColor = function () {
        let random = Math.random()*255;
        return Math.floor(random);
    };

    return {
        run:run
    }
    
})();

export default rainbowPack













